package com.ruoyi.business.api;

import com.alibaba.fastjson2.JSONObject;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.dingtalkrobot_1_0.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * @author JerryLu
 * @date 2024/8/2 9:20
 * @description 钉钉消息通知接口
 */
@Component
@Slf4j
@Configurable
public class DingDingApi {

    @Autowired
    private RedisCache redis;

    @Value("${dingtalk.appKey}")
    private String appKey;

    @Value("${dingtalk.robotCode}")
    private String robotCode;

    @Value("${dingtalk.appSecret}")
    private String appSecret;

    private String accessToken = null;

    private String serverUrl = "https://oapi.dingtalk.com/topapi/v2/user/getbymobile";

    /**
     * 初始化服务端API
     *
     * @author JerryLu
     * @date 2024/8/3 10:53
     */
    public void init() throws Exception {
        if (redis.hasKey("accessToken")) {
            accessToken = redis.getCacheObject("accessToken").toString();
        } else {
            com.aliyun.dingtalkoauth2_1_0.Client client = this.createClient2_1();
            com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest().setAppKey(appKey).setAppSecret(appSecret);
            try {
                GetAccessTokenResponse response = client.getAccessToken(getAccessTokenRequest);
                accessToken = response.getBody().getAccessToken();
                redis.setCacheObject("accessToken", accessToken, Math.toIntExact(response.getBody().getExpireIn()), TimeUnit.SECONDS);
            } catch (TeaException err) {
                if (StringUtils.isNotEmpty(err.code) && !StringUtils.isEmpty(err.message)) {
                    log.warn(err.message);
                    throw new Exception(err.message);
                }

            } catch (Exception _err) {
                TeaException err = new TeaException(_err.getMessage(), _err);
                if (StringUtils.isNotEmpty(err.code) && StringUtils.isNotEmpty(err.message)) {
                    log.warn(err.message);
                    throw new Exception(err.message);
                }
            }
        }
    }

    /**
     * 使用Token初始化账号Client-获取token
     *
     * @return Client
     * @author JerryLu
     * @date 2024/8/3 10:48
     */
    private com.aliyun.dingtalkoauth2_1_0.Client createClient2_1() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    /**
     * 发送Markdown消息
     *
     * @param message
     * @param mobiles
     * @author JerryLu
     * @date 2024/8/3 14:57
     * @return void
     */
    public AjaxResult sendMessage(String message, String[] mobiles) throws Exception {
        init();
        JSONObject json = new JSONObject();
        JSONObject info = JSONObject.parseObject(message);
        json.put("title", info.getString("title"));
        String text = String.format("> <font color=#FE2C24>提示：有新的%s任务，请查收</font>\n\n" +
                "\n\n" +
                " **%s：** %s\n\n" +
                " **单据编号：** %s\n\n" +
                " **产品名称（校核）：** %s\n\n" +
                " **产品重量（校核）：** %s吨\n\n" +
                " **发货公司：** %s\n\n" +
                " **收货单位：** %s\n\n" +
                " **处理时间：** %s", info.getString("type"), info.getString("number_name"), info.getString("receiptNo"), info.getString("billno"), info.getString("name"), info.getString("weight"),
                info.getString("fahuo"), info.getString("shouhuo"),  DateUtils.getTime());
        json.put("text", text);
        com.aliyun.dingtalkrobot_1_0.Client client = this.createClient1_0();
        BatchSendOTOHeaders batchSendOTOHeaders = new BatchSendOTOHeaders();
        batchSendOTOHeaders.xAcsDingtalkAccessToken = this.accessToken;
        BatchSendOTORequest batchSendOTORequest = new BatchSendOTORequest()
                .setRobotCode(appKey)
                .setUserIds(this.getUserIdByPhoneNumber(mobiles))
                .setMsgKey("sampleMarkdown")
                .setMsgParam(json.toString());
        try {
            BatchSendOTOResponse response = client.batchSendOTOWithOptions(batchSendOTORequest, batchSendOTOHeaders, new RuntimeOptions());
            if (response.getStatusCode() == 200) {
                return AjaxResult.success();
            }
        } catch (TeaException err) {
            if (StringUtils.isNotEmpty(err.code) && StringUtils.isNotEmpty(err.message)) {
                log.warn(err.message);
                throw new Exception(err.message);
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (StringUtils.isNotEmpty(err.code) && StringUtils.isNotEmpty(err.message)) {
                log.warn(err.message);
                throw new Exception(err.message);
            }
        }
        return AjaxResult.error();
    }

    /**
     * 使用Token初始化账号Client-发送消息
     *
     * @author JerryLu
     * @date 2024/8/3 14:56
     * @return com.aliyun.dingtalkrobot_1_0.Client
     */
    private com.aliyun.dingtalkrobot_1_0.Client createClient1_0() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkrobot_1_0.Client(config);
    }

    /**
     * 通过手机号获取用户userid
     *
     * @param mobiles
     * @author JerryLu
     * @date 2024/8/4 10:50
     * @return java.util.List<java.lang.String>
     */
    public List<String> getUserIdByPhoneNumber(String[] mobiles) throws Exception {
        init();
        List<String> userIds = new ArrayList<>();
        try {
            for (String i: mobiles) {
                DingTalkClient client = new DefaultDingTalkClient(this.serverUrl);
                OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
                req.setMobile(i);
                OapiV2UserGetbymobileResponse rsp = client.execute(req, this.accessToken);
                if (rsp.getErrcode() == 0) {
                    userIds.add(rsp.getResult().getUserid());
                }
            }
        } catch (ApiException e) {
            e.printStackTrace();
            log.warn(e.getErrMsg());
        }
        return userIds;
    }
}
